﻿using System;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using CNative.Cloud.CPlatform.Address;
using CNative.Cloud.CPlatform.Module;
using CNative.Cloud.CPlatform.Runtime.Client;
using CNative.Cloud.CPlatform.Runtime.Server;
using CNative.Cloud.CPlatform.Utilities;
using System.Net.Sockets;

namespace CNative.Cloud.CPlatform
{
    public class ClientHostedService : IHostedService
    {

        private readonly IServiceEntryManager _serviceEntryManager;
        private readonly IServiceSubscribeManager _serviceSubscribeManager;
        private readonly IModuleProvider _moduleProvider;

        public ClientHostedService(IServiceEntryManager serviceEntryManager,
            IServiceSubscribeManager serviceSubscribeManager,
            IServiceProvider serviceProvider,
            IModuleProvider moduleProvider)
        {
            _serviceEntryManager = serviceEntryManager;
            _serviceSubscribeManager = serviceSubscribeManager;
            _moduleProvider = moduleProvider;

            if (ServiceLocator.Current == null)
                ServiceLocator.Current = serviceProvider.GetAutofacRoot();
        }

        public async Task StartAsync(CancellationToken cancellationToken)
        {
            string ipa = "127.0.0.1";
            try
            {
                //var hostName = Dns.GetHostName();
                // ConsoleC.WriteLine($" is network available { System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()}", ConsoleColor.DarkGray);
                //ConsoleC.WriteLine($"StartAsync hostName={hostName}", ConsoleColor.DarkGray);

                //var addressList = Dns.GetHostAddresses(hostName)
                //    .Where(x => x.AddressFamily == AddressFamily.InterNetwork)
                //    .Select(ipAddress => ipAddress.ToString()).ToArray();
                //ConsoleC.WriteLine($"StartAsync hostName={hostName},addressList ={ string.Join(",", addressList)}", ConsoleColor.DarkGray);

                //if (addressList?.Length > 0)
                //    ipa = addressList[0];

               // var addressList = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces()
               //       .Select(i => i.GetIPProperties())
               //       .SelectMany(p => p.UnicastAddresses)
               //       .Where(p => p.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && !System.Net.IPAddress.IsLoopback(p.Address))
               //       .ToList();

               //ConsoleC.WriteLine($"ClientHostedService.StartAsync AddressList:\n{string.Join("\t", addressList?.Select(ip => ip?.Address))}", ConsoleColor.DarkGreen);

                ipa = NetUtils.GetAnyHostAddress();//addressList?.FirstOrDefault()?.Address.ToString();

                if (string.IsNullOrEmpty(ipa)) ipa = "127.0.0.1";

                ConsoleC.WriteLine($"ClientHostedService.StartAsync First Host Address={ipa}", ConsoleColor.DarkGreen);
            }
            catch (Exception ex)
            {
                ConsoleC.WriteLine(ex, $"new IpAddressModel Dns.GetHostName() ");
            }

            var addressDescriptors = _serviceEntryManager.GetEntries().Select(i =>
            {
                var serviceSubscriber = new ServiceSubscriber
                {
                    Address = new[] { new IpAddressModel { Ip = ipa } },
                    ServiceDescriptor = i.Descriptor
                };
                return serviceSubscriber;
            }).ToList();
            await _serviceSubscribeManager.SetSubscribersAsync(addressDescriptors);
            _moduleProvider.Initialize();
        }


        public async Task StopAsync(CancellationToken cancellationToken)
        {

        }
    }
}